
package image.util;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.prefs.Preferences;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;

public class MainFrame extends JFrame implements Observer {

    private final MainFrame frame = this;
    private JProgressBar bar;
    private Main model;
    private Preferences prefs;

    public MainFrame() {
        super("Image resizer");
        super.setDefaultCloseOperation(2);
        try {
            ResourceBundle rb = new PropertyResourceBundle(ClassLoader.getSystemResourceAsStream("Burdeos.properties"));
            String name;
            for (Iterator i$ = rb.keySet().iterator(); i$.hasNext(); System.setProperty(name, rb.getString(name))) {
                name = (String) i$.next();
            }

//            UIManager.setLookAndFeel("com.nilo.plaf.nimrod.NimRODLookAndFeel");
//            UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception e) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            }
            catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        setSize(640, 250);
        setResizable(false);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation((screenSize.width - getWidth()) / 2, (screenSize.height - getHeight()) / 2);

        prefs = Preferences.userRoot().node("resizer");
        model = new Main();
        model.addObserver(this);
        final JTextField dir = new JTextField(prefs.get("source.dir", ""));

        JButton browse = new JButton("Просмотр");

        final JFileChooser fileChooser = new JFileChooser();
        fileChooser.setFileSelectionMode(1);
        fileChooser.setFileFilter(new FileFilter() {
            public boolean accept(File file) {
                return file.isDirectory();
            }

            public String getDescription() {
                return "directories";
            }
        });

        browse.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (dir.getText() != null && !dir.getText().equals("")) {
                    fileChooser.setSelectedFile(new File(dir.getText()));
                }
                int res = fileChooser.showOpenDialog(frame);
                if (res == 0) {
                    dir.setText(fileChooser.getSelectedFile().getAbsolutePath());
                }
            }
        });
        final JTextField dirTo = new JTextField(prefs.get("target.dir", ""));
        JButton browseTo = new JButton("Просмотр");
        browseTo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (dirTo.getText() != null && !dirTo.getText().equals("")) {
                    fileChooser.setSelectedFile(new File(dir.getText()));
                }
                int res = fileChooser.showOpenDialog(frame);
                if (res == 0) {
                    dirTo.setText(fileChooser.getSelectedFile().getAbsolutePath());
                }
            }
        });

        final JSpinner ws = new JSpinner(new SpinnerNumberModel(prefs.getInt("size.width", 2000), 100, 5000, 100));
        final JSpinner hs = new JSpinner(new SpinnerNumberModel(prefs.getInt("size.height", 1500), 100, 5000, 100));
        final JSpinner maxs = new JSpinner(new SpinnerNumberModel(prefs.getInt("size.max", 2000), 100, 5000, 100));
        final JCheckBox box = new JCheckBox();
        box.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                ws.setEnabled(!box.isSelected());
                hs.setEnabled(!box.isSelected());
                maxs.setEnabled(box.isSelected());
            }
        });
        box.doClick();
        final JButton start = new JButton("Начать обработку");
        start.setEnabled(!dir.getText().isEmpty() && !dirTo.getText().isEmpty());
        final JButton stop = new JButton("Остановить");
        stop.setEnabled(false);

        DocumentListener listener = new DocumentListener() {
            public void insertUpdate(DocumentEvent e) {
                process();
            }

            public void removeUpdate(DocumentEvent e) {
                process();
            }

            public void changedUpdate(DocumentEvent e) {
                process();
            }

            private void process() {
                start.setEnabled(dir.getText().length() > 0 && dirTo.getText().length() > 0);
            }
        };

        dir.getDocument().addDocumentListener(listener);
        dirTo.getDocument().addDocumentListener(listener);
        
        start.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                prefs.put("source.dir", dir.getText());
                prefs.put("target.dir", dirTo.getText());
                prefs.putInt("size.width", (Integer) ws.getValue());
                prefs.putInt("size.height", (Integer) hs.getValue());
                prefs.putInt("size.max", (Integer) maxs.getValue());
                Thread t = new Thread(new Runnable() {
                    public void run() {
                        if (box.isSelected()) {
                            model.process(new String[]{
                                    dir.getText(), dirTo.getText(), String.valueOf(maxs.getValue())
                            });
                        } else {
                            model.process(new String[]{
                                    dir.getText(), dirTo.getText(), String.valueOf(ws.getValue()), String.valueOf(hs.getValue())
                            });
                        }
                        SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                start.setEnabled(true);
                                stop.setEnabled(false);
                            }
                        });
                    }
                });
                start.setEnabled(false);
                stop.setEnabled(true);
                t.start();
            }
        });


        stop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                model.stop();
                stop.setEnabled(false);
                start.setEnabled(true);
            }
        });


        bar = new JSmoothProgressBar(0, 100);
        bar.setStringPainted(true);
        GridBagLayout gb = new GridBagLayout();
        getContentPane().setLayout(gb);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = 2;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.weightx = 0.0D;
        getContentPane().add(new JLabel("Директория с изображениями:"), gbc);
        gbc.weightx = 1.0D;
        getContentPane().add(dir, gbc);
        gbc.weightx = 0.0D;
        gbc.gridwidth = 0;
        getContentPane().add(browse, gbc);
        gbc.weightx = 1.0D;
        gbc.weightx = 0.0D;
        gbc.gridwidth = 1;
        getContentPane().add(new JLabel("Сохранить в директорию:"), gbc);
        gbc.weightx = 1.0D;
        getContentPane().add(dirTo, gbc);
        gbc.weightx = 0.0D;
        gbc.gridwidth = 0;
        getContentPane().add(browseTo, gbc);
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createTitledBorder("Размер изображения"));
        panel.add(new JLabel("Сохранить пропорции:"));
        panel.add(box);
        panel.add(new JLabel("максимум"));
        panel.add(maxs);
        panel.add(new JLabel("ширина"));
        panel.add(ws);
        panel.add(new JLabel("высота"));
        panel.add(hs);
        gbc.weightx = 1.0D;
        gbc.gridwidth = 0;
        getContentPane().add(panel, gbc);
        getContentPane().add(bar, gbc);
        gbc.fill = GridBagConstraints.HORIZONTAL;
        final JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 8, 8));
        buttonPanel.add(start);
        buttonPanel.add(stop);
        getContentPane().add(buttonPanel, gbc);
        SwingUtilities.updateComponentTreeUI(frame);
    }

    public void update(Observable observable, Object o) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                if (model.getError() != null) {
                    JOptionPane.showMessageDialog(frame, model.getError());
                } else if (model.getTotalFiles() == 0) {
                    bar.setValue(100);
                } else {
                    bar.setValue((model.getProcessedFiles() * 100) / model.getTotalFiles());
                    if (model.getProcessedFiles() == model.getTotalFiles()) {
                        JOptionPane.showMessageDialog(frame, "Обработка изображений успешно завершена!");
                    }
                }
            }
        });
    }


    public static void main(String args[]) throws InvocationTargetException, InterruptedException {
        SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                new MainFrame().setVisible(true);
            }
        });
    }
}
